/**
 * 地图坐标转换工具类
 *
 * 坐标系说明：
 * 1. 屏幕坐标系：触摸事件返回的坐标，原点在屏幕左上角
 * 2. 原始图片坐标系：地图图片的像素坐标，原点在图片左上角，与缩放/平移无关
 * 3. 显示坐标系：经过缩放和平移后的坐标
 *
 * 变换矩阵：
 * [a  c  e]   [scale  0      offsetX]
 * [b  d  f] = [0      scale  offsetY]
 * [0  0  1]   [0      0      1      ]
 */

export class CoordinateTransform {
  /**
   * 构造函数
   * @param {Object} config - 配置参数
   * @param {Number} config.scale - 当前缩放比例
   * @param {Number} config.offsetX - 地图X轴偏移量（mapPosition.x）
   * @param {Number} config.offsetY - 地图Y轴偏移量（mapPosition.y）
   */
  constructor(config = {}) {
    this.scale = config.scale || 1
    this.offsetX = config.offsetX || 0
    this.offsetY = config.offsetY || 0
  }

  /**
   * 更新变换参数
   * @param {Object} config - 配置参数
   */
  update(config) {
    if (config.scale !== undefined) this.scale = config.scale
    if (config.offsetX !== undefined) this.offsetX = config.offsetX
    if (config.offsetY !== undefined) this.offsetY = config.offsetY
  }

  /**
   * 屏幕坐标 → 原始图片坐标（逆向变换）
   * 用于：用户长按/点击地图时，将触摸位置转换为原始图片坐标以保存
   *
   * 公式：
   * originalX = (screenX - offsetX) / scale
   * originalY = (screenY - offsetY) / scale
   *
   * @param {Number} screenX - 屏幕X坐标
   * @param {Number} screenY - 屏幕Y坐标
   * @returns {Object} { x, y } 原始图片坐标
   */
  screenToOriginal(screenX, screenY) {
    const originalX = (screenX - this.offsetX) / this.scale
    const originalY = (screenY - this.offsetY) / this.scale

    return {
      x: Number(originalX.toFixed(1)),
      y: Number(originalY.toFixed(1))
    }
  }

  /**
   * 原始图片坐标 → 屏幕坐标（正向变换）
   * 用于：显示标记点时，将保存的原始坐标转换为屏幕坐标
   *
   * 公式：
   * screenX = originalX * scale + offsetX
   * screenY = originalY * scale + offsetY
   *
   * @param {Number} originalX - 原始图片X坐标
   * @param {Number} originalY - 原始图片Y坐标
   * @returns {Object} { x, y } 屏幕坐标
   */
  originalToScreen(originalX, originalY) {
    const screenX = originalX * this.scale + this.offsetX
    const screenY = originalY * this.scale + this.offsetY

    return {
      x: Number(screenX.toFixed(1)),
      y: Number(screenY.toFixed(1))
    }
  }

  /**
   * 获取当前变换矩阵信息（用于调试）
   * @returns {Object} 变换矩阵参数
   */
  getMatrix() {
    return {
      scale: this.scale,
      offsetX: this.offsetX,
      offsetY: this.offsetY
    }
  }

  /**
   * 以指定点为中心进行缩放
   * 用于：实现以鼠标/触摸点为中心的缩放效果
   *
   * 原理：先将中心点移到原点，缩放，再移回去
   *
   * @param {Number} centerX - 缩放中心点X坐标（屏幕坐标）
   * @param {Number} centerY - 缩放中心点Y坐标（屏幕坐标）
   * @param {Number} newScale - 新的缩放比例
   * @returns {Object} { offsetX, offsetY } 新的偏移量
   */
  scaleAtPoint(centerX, centerY, newScale) {
    // 计算中心点在原始图片中的位置
    const originalPoint = this.screenToOriginal(centerX, centerY)

    // 计算新的偏移量，使得缩放后中心点保持在原位置
    const newOffsetX = centerX - originalPoint.x * newScale
    const newOffsetY = centerY - originalPoint.y * newScale

    return {
      offsetX: Number(newOffsetX.toFixed(1)),
      offsetY: Number(newOffsetY.toFixed(1))
    }
  }
}

/**
 * 工具函数：创建变换实例
 * @param {Object} config - 配置参数
 * @returns {CoordinateTransform} 变换实例
 */
export function createTransform(config) {
  return new CoordinateTransform(config)
}

export default CoordinateTransform
